cmake_minimum_required(VERSION 3.16)
project(xdevice LANGUAGES C)

# Set C standard
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)

# Compile options
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -pthread -fPIC -D_GNU_SOURCE")
set(CMAKE_C_FLAGS_DEBUG "-g -O0")
set(CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG")

# Set default build type
if(NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE Release)
endif()

# Include directories
include_directories(include)

# Find dependencies
find_package(Threads REQUIRED)

# Source files
file(GLOB_RECURSE CORE_SOURCES "src/core/*.c")
file(GLOB_RECURSE RAFT_SOURCES "src/raft/*.c")
file(GLOB_RECURSE CONSENSUS_SOURCES "src/consensus/*.c")
file(GLOB_RECURSE STORAGE_SOURCES "src/storage/*.c")
file(GLOB_RECURSE TRANSPORT_SOURCES "src/transport/*.c")
file(GLOB_RECURSE RPC_SOURCES "src/rpc/*.c")

# Create static library
add_library(xdevice_static STATIC
    ${CORE_SOURCES}
    ${RAFT_SOURCES}
    ${CONSENSUS_SOURCES}
    ${STORAGE_SOURCES}
    ${TRANSPORT_SOURCES}
    ${RPC_SOURCES}
)
target_link_libraries(xdevice_static Threads::Threads rt m)

# Create shared library
add_library(xdevice SHARED
    ${CORE_SOURCES}
    ${RAFT_SOURCES}
    ${CONSENSUS_SOURCES}
    ${STORAGE_SOURCES}
    ${TRANSPORT_SOURCES}
    ${RPC_SOURCES}
)
target_link_libraries(xdevice Threads::Threads rt m)

# Set library output names
set_target_properties(xdevice_static PROPERTIES OUTPUT_NAME xdevice)
set_target_properties(xdevice PROPERTIES OUTPUT_NAME xdevice)

# Executables
add_executable(xdevice-node src/main/node_main.c)
target_link_libraries(xdevice-node xdevice)

add_executable(xdevice-cli src/main/cli_main.c)
target_link_libraries(xdevice-cli xdevice)

add_executable(xdevice-monitor tools/xdevice-monitor.c)
target_link_libraries(xdevice-monitor xdevice)

# Tests
option(BUILD_TESTS "Build tests" ON)

if(BUILD_TESTS)
    # Test executables
    add_executable(test_library_basic tests/test_library_basic.c tests/test_helpers.c)
    target_link_libraries(test_library_basic xdevice_static)
    
    add_executable(test_integrated_rpc tests/test_integrated_rpc.c tests/test_helpers.c)
    target_link_libraries(test_integrated_rpc xdevice_static)
    
    add_executable(test_xdevice_functionality tests/test_xdevice_functionality.c tests/test_helpers.c)
    target_link_libraries(test_xdevice_functionality xdevice_static)
    
    add_executable(test_raft_multi_thread tests/test_raft_multi_thread.c tests/test_helpers.c)
    target_link_libraries(test_raft_multi_thread xdevice_static)
    
    add_executable(test_raft_multi_process tests/test_raft_multi_process.c tests/test_helpers.c)
    target_link_libraries(test_raft_multi_process xdevice_static)
    
    add_executable(test_three_replica_data tests/test_three_replica_data.c)
    target_link_libraries(test_three_replica_data xdevice_static)
    
    # Enable testing
    enable_testing()
    add_test(NAME functionality_test COMMAND test_xdevice_functionality)
    add_test(NAME multi_thread_test COMMAND test_raft_multi_thread)
    add_test(NAME multi_process_test COMMAND test_raft_multi_process)
    
    # Test targets
    add_custom_target(test-basic
        COMMAND test_library_basic
        DEPENDS test_library_basic
        COMMENT "Running basic library functionality test"
    )
    
    add_custom_target(test-integrated
        COMMAND test_integrated_rpc
        DEPENDS test_integrated_rpc
        COMMENT "Running integrated RPC test"
    )
    
    add_custom_target(test-functionality
        COMMAND test_xdevice_functionality
        DEPENDS test_xdevice_functionality
        COMMENT "Running XDevice functionality test"
    )
    
    add_custom_target(test-multi-thread
        COMMAND test_raft_multi_thread
        DEPENDS test_raft_multi_thread
        COMMENT "Running multi-thread Raft cluster test"
    )
    
    add_custom_target(test-multi-process
        COMMAND test_raft_multi_process
        DEPENDS test_raft_multi_process
        COMMENT "Running multi-process Raft cluster test"
    )
    
    add_custom_target(test-three-replica
        COMMAND test_three_replica_data
        DEPENDS test_three_replica_data
        COMMENT "Running three-replica data replication test"
    )
    
    add_custom_target(test-all
        DEPENDS test_library_basic test_integrated_rpc test_xdevice_functionality test_raft_multi_thread test_raft_multi_process test_three_replica_data
        COMMENT "Running all tests"
    )
endif()

# Installation rules
install(TARGETS xdevice xdevice_static xdevice-node xdevice-cli xdevice-monitor
    RUNTIME DESTINATION bin
    LIBRARY DESTINATION lib
    ARCHIVE DESTINATION lib
)

install(DIRECTORY include/xdevice DESTINATION include)

# Configuration file
configure_file(
    "${CMAKE_CURRENT_SOURCE_DIR}/cmake/xdevice.pc.in"
    "${CMAKE_CURRENT_BINARY_DIR}/xdevice.pc"
    @ONLY
)

install(FILES "${CMAKE_CURRENT_BINARY_DIR}/xdevice.pc"
    DESTINATION lib/pkgconfig
)

# Print build information
message(STATUS "XDevice Build Configuration:")
message(STATUS "  Build Type: ${CMAKE_BUILD_TYPE}")
message(STATUS "  C Compiler: ${CMAKE_C_COMPILER}")
message(STATUS "  C Flags: ${CMAKE_C_FLAGS}")
message(STATUS "  Install Prefix: ${CMAKE_INSTALL_PREFIX}")
message(STATUS "  Build Tests: ${BUILD_TESTS}")
